package states
{
	import assets.Globals;
	import assets.Images;
	
	import collision.CollisionList;
	
	import com.greensock.TweenMax;
	import com.greensock.easing.Linear;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.TimerEvent;
	import flash.ui.Keyboard;
	import flash.utils.Timer;
	
	import gameobjects.*;
	import gameobjects.enemies.*;
	import gameobjects.towers.*;
	
	import logic.*;
	import logic.Score;
	
	import managers.*;
	
	public class Game extends Sprite
	{
		private var onPause:Function;
		
		public function Game(onPause:Function)
		{
		//	SoundManager.mainMusic();
			this.onPause = onPause;
			
			// draw
			addChild(Math.random() > .5 ? Images.gameBackground1 : Images.gameBackground2);
			addChild(Score.createHeaderScore());

			Globals.game = this;

			Globals.towersMap = new Map();
			
			var menu:MenuBar = new MenuBar();
			addChild(menu);
				
			addEventListener(Event.ADDED_TO_STAGE, init);
			
			Globals.towerDropper = new TowerDropper(towerDroppedHandler);
			towerDrop = Globals.towerDropper;
		}
		
		private function init(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		public function start():void
		{
			CreepManager.start();
		}
		
		public function pause(i:int = 3):void
		{
			TweenMax.pauseAll();
			CreepManager.pause();
			for each (var tower:Tower in Globals.towers)
				tower.pause();
			for each (var enemy:Enemy in Globals.enemies)
				enemy.pause();
			onPause(i);
		}
		
		public function resume():void
		{
			TweenMax.resumeAll();
			CreepManager.resume();
			for each (var tower:Tower in Globals.towers)
				tower.resume();
			for each (var enemy:Enemy in Globals.enemies)
				enemy.resume();
		}
		
		/**
		 * Shaker
		 */
		private var canShake:Boolean = true;
		private var shakerX: Number;
		private var shakerY: Number;
		private function shakerTimerHandler(event:TimerEvent):void
		{
			shakerX = Math.random() * 20 - 10;
			shakerY = Math.random() * 20 - 10;
			Globals.game.x = shakerX;
			Globals.game.y = shakerY;
			
			for each (var enemy:Enemy in Globals.enemies) enemy.decreaseHealth(3);
			for each (var tower:Tower in Globals.towers) tower.decreaseHealth(3);
		}
		
		private function shakerTimerCompleteHandler(event:TimerEvent):void
		{
			Globals.game.x = 0;
			Globals.game.y = 0;
			
			var cooldownTimer:Timer = new Timer(500, 20);
			cooldownTimer.addEventListener(TimerEvent.TIMER, cooldownTimerHandler);
			cooldownTimer.addEventListener(TimerEvent.TIMER_COMPLETE, cooldownTimerCompleteHandler);
			cooldownTimer.start();
		}
		private function cooldownTimerHandler(event:TimerEvent):void
		{
			
		}
		private function cooldownTimerCompleteHandler(event:TimerEvent):void
		{
			canShake = true;
		}
		//// SHAKER ^^
		
		private var towerDrop:TowerDropper;
		
		private function towerDroppedHandler(x:int, y:int, tower:Tower):void
		{
			if (tower is Marine)
				Money.decMoney();
			else if (tower is Cannon)
				Money.decMoney(4);
			else
				throw Error("Koliko je ta kula para? :D");
			tower.Activate();
			Globals.towers.push(tower);
			Globals.towersMap.putTower(x, y, tower);
			tower.setFieldX(x);
			tower.setFieldY(y);
		}
		
		public function keyUpHandler(event:KeyboardEvent):void
		{
			switch (event.keyCode) {
				/**
				 * Drugi marinac
				 */
				case Keyboard.NUMBER_1:
					if (Money.getMoney() >= Marine.getPrice()
						&& !towerDrop.isActive())
						towerDrop.start(new Marine());
					break;
				/**
				 * Prvi marinac
				 */
				case Keyboard.NUMBER_2:
					if (Money.getMoney() >= Cannon.getPrice()
						&& !towerDrop.isActive())
						towerDrop.start(new Cannon());
					break;
				/**
				 * aktivira pauzu
				 */
				case Keyboard.ESCAPE:
					if (towerDrop.isActive())
						towerDrop.stop();
					else
						this.pause();
					break;
				/**
				 * MAP SHAKER
				 */
				case Keyboard.SPACE:
				{
					if (canShake) {
						var shakerTimer:Timer = new Timer(60, 20);
						shakerTimer.addEventListener(TimerEvent.TIMER, shakerTimerHandler);
						shakerTimer.addEventListener(TimerEvent.TIMER_COMPLETE, shakerTimerCompleteHandler);
						shakerTimer.start();
						canShake = false;
					}
				}
			}
		}
		
		public function enterFrameHanler(event:Event):void
		{
			if (Score.getEnemiesKilled() > 40) {
				pause(2);
			}
			
			if (Money.getMoney() < 0) {
				pause(2);
			}
			
			for each (var enemy:Enemy in Globals.enemies) 
			{
				// ako Enemy izadje iz screena
				if (enemy.x < -80)
				{
					Score.incEnemiesEscaped();
					Money.decMoney(enemy.getValue());
					enemy.destroy();
					continue;
				}
				
				for each (var projectile:TowerProjectile in Globals.projectiles) {
					// ako Projektil izadje iz screena
					if (projectile.x > Globals.SCREEN_WIDTH) 
					{
						projectile.destroy();
						continue;
					}
					// ako Projektil uradi u Enemy-ja
					if (enemy.cs.hitTestObject(projectile.cs)) {
						projectile.hit(enemy);
						continue;
					}
				}
				
				var attack:Boolean = false;
				
				for each (var tower1:Tower in Globals.towers) {
					if (enemy.cs.hitTestObject(tower1.cs)) {
						if (!enemy.isAttacking() && !enemy.isShifting()) {
							if (Math.random() > .75) {
								enemy.shift();
							} else {
								enemy.attack();
								attack = true;
							}
						}
						if (enemy.isAttacking()) attack = true;	
					}
				}
				
				if (!attack && enemy.isAttacking())
					enemy.move();
			}
			
			for each (var tower0:Tower in Globals.towers)
			{
				for each (var invisible:InvisibleProjectile in Globals.invisibles)
				{
					if (tower0.cs.hitTestObject(invisible.cs))
					{
						if (invisible.hit(tower0))
							invisible.getAttacker().move();
						continue;
					}
				}
			}
		}
		

	}
}